Fix macOS 15.5 port availability with localhost fallback to 127.0.0.1#4703
Fix macOS 15.5 port availability with localhost fallback to 127.0.0.1#4703
Conversation
Co-authored-by: illume <9541+illume@users.noreply.github.com>
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: Copilot The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
- Add isPortAvailableOnHost() helper function to check port on specific host - Modify isPortAvailable() to try localhost first, then 127.0.0.1 as fallback - Track working host address in actualHost variable - Update server listen address to use actualHost - Update browser connection URLs to use actualHost - Improve error messages to indicate which host addresses were tried Co-authored-by: illume <9541+illume@users.noreply.github.com>
Co-authored-by: illume <9541+illume@users.noreply.github.com>
- Created app/electron/portUtils.ts with port checking functions - Created app/electron/portUtils.test.ts with comprehensive tests - Improved error messages for localhost resolution failures - Added createLocalhostErrorMessage() with troubleshooting steps - Updated main.ts to use the new portUtils module - Removed net import from main.ts (no longer needed) Co-authored-by: illume <9541+illume@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR aims to fix Headlamp Desktop startup failures on macOS 15.5 by improving port availability detection: probing localhost first and falling back to 127.0.0.1, then using the successful host consistently for server bind and browser/Electron URLs.
Changes:
- Added
app/electron/portUtils.tswith port probing + richer error messages. - Updated
app/electron/main.tsto use the new probing logic, persist the chosen host, and update URL handling accordingly. - Added Jest coverage in
app/electron/portUtils.test.tsfor the new utilities.
Reviewed changes
Copilot reviewed 3 out of 5 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| frontend/package-lock.json | Lockfile metadata churn (adds many "peer": true entries). |
| app/package-lock.json | Lockfile metadata churn (adds/removes "peer": true, removes other flags). |
| app/electron/portUtils.ts | New port probing helpers + error message builders. |
| app/electron/portUtils.test.ts | New Jest tests for port probing + message builders. |
| app/electron/main.ts | Uses new probing results to choose host/port and updates URLs accordingly. |
Files not reviewed (2)
- app/package-lock.json: Language not supported
- frontend/package-lock.json: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@copilot revert all the changes and just swap |
As requested by @sniok, reverted the complex fallback mechanism and simply replaced 'localhost' with '127.0.0.1' in: - isPortAvailable() function for port checking - Server --listen-addr argument - Browser connection URLs - Cookie handling URL checks This is a minimal change that fixes the macOS 15.5 issue where localhost resolution fails. Co-authored-by: sniok <4517681+sniok@users.noreply.github.com>
Done. Reverted all changes and replaced |
Changes per @illume's request: 1. Differentiate EADDRINUSE (port occupied) from resolution errors - Only trigger fallback for resolution errors (ENOTFOUND, EADDRNOTAVAIL, etc.) - EADDRINUSE means port is occupied, no fallback needed 2. Remove noisy console.warn from checkPortAvailability - Only warn once in findAvailablePort when resolution failure detected 3. Add IPv6 (::1) as third fallback after 127.0.0.1 4. Update tests to be deterministic (use OS-assigned ports) 5. Test EADDRINUSE behavior correctly 6. Revert unrelated package-lock.json changes 7. Update interface: localhostFailed → resolutionFailed, add errorCode 8. Update error messages to mention IPv6 Co-authored-by: illume <9541+illume@users.noreply.github.com>
Addressed all review comments and added IPv6 fallback:
Commit: 8b8d09f |
|
@copilot run the app tests and fix the errors |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Fixed test: bind to 'localhost' instead of '0.0.0.0' for reliable EADDRINUSE behavior - Added formatHostForURL() helper to wrap IPv6 addresses in brackets for URL syntax - Updated URL constructions to use formatHostForURL() for proper IPv6 support - All tests pass (48/48) - Linting and formatting pass Co-authored-by: illume <9541+illume@users.noreply.github.com>
Tests fixed and passing (48/48). Also added IPv6 URL formatting:
Commit: 0e6ab6f |
- Removed app/electron/portUtils.js and portUtils.test.js (compiled files) - Added .gitignore to exclude compiled JS files - These files are generated during test compilation and shouldn't be committed Co-authored-by: illume <9541+illume@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 6 changed files in this pull request and generated 2 comments.
Files not reviewed (2)
- app/package-lock.json: Language not supported
- frontend/package-lock.json: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@copilot address open review comments |
- Fixed IPv6 fallback logic: try both IPv4 and IPv6 independently when localhost fails with resolution error - Improved formatHostForURL() to check for specific IPv6 patterns (::1, ::, fe80:) instead of any colon - Updated actualHost comment to mention ::1 as possible value - Added IPv6 (::1) test with graceful skip if IPv6 not available - All 49 tests passing - Linting and formatting pass Co-authored-by: illume <9541+illume@users.noreply.github.com>
Addressed both review comments:
All tests passing (49/49). Commit: 808f047 |
- formatHostForURL() now uses robust IPv6 detection: has colon AND no dot (distinguishes IPv6 from IPv4, avoids false positives on hostname:port) - IPv6 test now properly validates function behavior even when IPv6 unavailable (tests that function returns error instead of crashing) - All 49 tests still passing Co-authored-by: illume <9541+illume@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 6 changed files in this pull request and generated no new comments.
Files not reviewed (2)
- app/package-lock.json: Language not supported
- frontend/package-lock.json: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Fix macOS 15.5 port availability with smart fallback (localhost → 127.0.0.1 → ::1)
Solution Approach
Implements a smart fallback mechanism that tries
localhostfirst, then falls back to127.0.0.1and::1independently when actual resolution/configuration errors occur (not just port occupied).Changes
Updated:
app/electron/portUtils.tsisPortAvailableOnHost()returns error code to differentiate failure typescheckPortAvailability()checks error codes:EADDRINUSE= port occupied, no fallback neededENOTFOUND,EADDRNOTAVAIL,EAFNOSUPPORT,ENETUNREACH= resolution error, try fallbacksconsole.warnfrom utility (caller decides when to warn)resolutionFailedflag,errorCodefield for debuggingUpdated:
app/electron/main.tsfindAvailablePort()warns once when resolution failure detected (includes error code)resolutionFailedflag to distinguish resolution failures from port occupationformatHostForURL()helper for proper IPv6 URL formattingformatHostForURL()Updated:
app/electron/portUtils.test.tsAdded: app/electron/.gitignore
Reverted: package-lock.json files
Why This Approach
Testing
Note
Addresses ALL review comments from copilot-pull-request-reviewer bot including the latest round. Implements full IPv6 support with independent fallback logic as requested by @illume.
Original prompt
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.